package com.tuanzi.loan.business.service.xhh.settlementsystem.impl;

import com.tuanzi.loan.business.entity.xhh.settlementsystem.XhhSettlementCompany;
import com.tuanzi.loan.business.entity.xhh.settlementsystem.XhhSettlementPrepay;
import com.tuanzi.loan.business.repository.xhh.settlementsystem.XhhSettlementCompanyRepository;
import com.tuanzi.loan.business.repository.xhh.settlementsystem.XhhSettlementPrepayRepository;
import com.tuanzi.loan.business.repository.xhh.settlementsystem.XhhSettlementRemainRepository;
import com.tuanzi.loan.business.service.xhh.settlementsystem.XhhBillStatus;
import com.tuanzi.loan.business.service.xhh.settlementsystem.XhhSettlementPrepayService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.repository.JPAAuditRepository;
import com.tuanzi.loan.core.service.BaseAuditServiceImpl;
import com.tuanzi.loan.core.vo.PageSearcher;
import com.tuanzi.loan.vo.request.xhh.settlementsystem.XhhSettlementPrepayRequest;
import com.tuanzi.loan.vo.response.xhh.settlementsystem.XhhSettlementPrepayResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.retry.RetryException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author caiwanlin
 * @create 2018-08-22 17:39
 */
@Debug
@Service
@Transactional
@Retryable(value = {RetryException.class})
public class XhhSettlementPrepayServiceImpl extends BaseAuditServiceImpl<XhhSettlementPrepay, Long> implements XhhSettlementPrepayService {

    @Autowired
    private XhhSettlementPrepayRepository xhhSettlementPrepayRepository;
    @Autowired
    private XhhSettlementCompanyRepository xhhSettlementCompanyRepository;
    @Autowired
    private XhhSettlementRemainRepository xhhSettlementRemainRepository;

    private ReentrantLock lock = new ReentrantLock();

    @Override
    protected JPAAuditRepository<XhhSettlementPrepay, Long> getRepository() {
        return xhhSettlementPrepayRepository;
    }

    @Override
    public Page<XhhSettlementPrepayResponse> list(PageSearcher<XhhSettlementPrepayRequest> pageSearcher) {
        return xhhSettlementPrepayRepository.list(pageSearcher.getSearchCondition(), pageSearcher.getPageable());
    }

    @Override
    public void onSave(XhhSettlementPrepay settlementPrepay) {
        Long settlementPrepayId = settlementPrepay.getId();

        //如果是添加，未开票状态
        if (settlementPrepayId == null) settlementPrepay.setBillStatus(XhhBillStatus.NO_BILL.index);

        //更新公司的预付金额

        XhhSettlementCompany company = null;
        Double settlementPrepayAmount = null;//充值金额
        Double companyPrepayAmount = null;
        Double lastPrepayAmount = settlementPrepay.getLastPrepayAmount();//最后一次预付金额
        try {
            lock.lock();//保证只有一个线程在执行更新操作
            company = xhhSettlementCompanyRepository.findOne(settlementPrepay.getCompanyId());
            companyPrepayAmount = company.getPrepayAmount();
            settlementPrepayAmount = settlementPrepay.getPrepayAmount();
            if (companyPrepayAmount == null){
                company.setPrepayAmount(settlementPrepayAmount);
            }
            else {
                if (settlementPrepayId == null){ //如果是添加预付记录，公司的预付金额 = 原始预付金额+充值金额
                    company.setPrepayAmount(companyPrepayAmount + settlementPrepayAmount);
                }
                else {//如果是修改预付记录 ， 公司的预付金额 = 原始预付金额 - 最后一次充值金额 + 要更新的充值金额
                    if (lastPrepayAmount != settlementPrepayAmount){
                        company.setPrepayAmount(companyPrepayAmount - lastPrepayAmount + settlementPrepayAmount);
                    }
                }
            }
            xhhSettlementCompanyRepository.save(company);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        //保存预付记录
        settlementPrepay.setLastPrepayAmount(settlementPrepayAmount);//设置最后一次更新金额
        xhhSettlementPrepayRepository.save(settlementPrepay);

        //插入余额记录
        /*SettlementRemain settlementRemain = null;
        if (settlementPrepayId == null){
            settlementRemain = new SettlementRemain();
            settlementRemain.setCompanyId(company.getId());
            settlementRemain.setCompanyName(company.getCompanyName());
            settlementRemain.setRemainType(RemainType.PREPAY.index);
            settlementRemain.setRelateId(settlementPrepay.getId());
            settlementRemain.setPrePrepayAmount(companyPrepayAmount==null?0:companyPrepayAmount);
            settlementRemain.setPrepayAmount(company.getPrepayAmount());
            settlementRemain.setPreExpendAmount(company.getExpendAmount());
            settlementRemain.setExpendAmount(company.getExpendAmount());
            settlementRemain.setPreRemainAmount(settlementRemain.getPrePrepayAmount()-settlementRemain.getPreExpendAmount());
            settlementRemain.setRemainAmount(settlementRemain.getPrepayAmount()-settlementRemain.getExpendAmount());
            settlementRemainRepository.save(settlementRemain);
        }
        else {
            if (lastPrepayAmount == settlementPrepayAmount) return;
            settlementRemain = settlementRemainRepository
                    .findSettlementRemainByRelateIdAndRemainType(settlementPrepayId,RemainType.PREPAY.index);
            Double oldPrePrepayAmount = settlementRemain.getPrePrepayAmount();
            Double oldPrepayAmount = settlementRemain.getPrepayAmount();
            //更新预付金额
//            settlementRemain.setPrePrepayAmount(oldPrePrepayAmount - lastPrepayAmount);
            settlementRemain.setPrepayAmount(oldPrepayAmount - lastPrepayAmount + settlementPrepayAmount);
            //更新剩余金额
            settlementRemain.setPreRemainAmount(settlementRemain.getPrePrepayAmount() - settlementRemain.getPreExpendAmount());
            settlementRemain.setRemainAmount(settlementRemain.getPrepayAmount() - settlementRemain.getExpendAmount());
            settlementRemainRepository.save(settlementRemain);
        }*/
    }

    @Override
    public List<XhhSettlementPrepay> findAllByBillId(Long billId) {
        return xhhSettlementPrepayRepository.findAllByBillId(billId);
    }

    @Override
    public List<XhhSettlementPrepay> findAllByCompanyId(Long companyId) {
        return xhhSettlementPrepayRepository.findAllByCompanyId(companyId);
    }

    @Override
    public void onDelete(Long id) {
        XhhSettlementPrepay prepay = xhhSettlementPrepayRepository.findOne(id);
        if (null == prepay) {
            return;
        }

        XhhSettlementCompany company = xhhSettlementCompanyRepository.findOne(prepay.getCompanyId());
        if (null == company) {
            return;
        }

        Double companyPrepayAmount = company.getPrepayAmount();
        Double prepayAmount = prepay.getPrepayAmount();
        company.setExpendAmount(companyPrepayAmount - prepayAmount);
        xhhSettlementCompanyRepository.save(company);

        xhhSettlementPrepayRepository.delete(prepay);
    }


    @Override
    public Double getToTalOrderCount(XhhSettlementPrepayRequest $) {
        return xhhSettlementPrepayRepository.getToTalOrderCount($);
    }

    @Override
    public Double getAliOrderCount(XhhSettlementPrepayRequest $) {
        return xhhSettlementPrepayRepository.getAliOrderCount($);
    }

    @Override
    public Double getBankOrderCount(XhhSettlementPrepayRequest $) {
        return xhhSettlementPrepayRepository.getBankOrderCount($);
    }

    @Override
    public Double getWechatOrderCount(XhhSettlementPrepayRequest $) {
        return xhhSettlementPrepayRepository.getWechatOrderCount($);
    }
}
